/*
 * \copyright Copyright 2013 Google Inc. All Rights Reserved.
 * \license @{
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @}
 */
/*
 * \license @{
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @}
 */
// Copyright (C) 2001 Google, Inc.
//
//
// Callback classes provide a generic interface for classes requiring
// callback from other classes. See the following codelab for details:
//
// We support callbacks with multiple arguments.
//   Closure                  -- provides "void Run()"
//   Callback1<T1>            -- provides "void Run(T1)"
//   Callback2<T1,T2>         -- provides "void Run(T1, T2)"
//   ResultCallback1<R,T1>    -- provides "R Run(T1)"
//   ...
//
// Arguments can be pre-bound; see the Examples section below for examples.
//
// Callbacks are created via NewCallback and NewPermanentCallback functions.
// The former creates self-destructible callback which can _only_ be called
// once. So you MUST use the latter if you're planning on using a callback
// more than once. The CheckIsRepeatable() method is provided in any callback
// to die if it is not permanent (aka repeatable).
//
// Examples:
//
//   void Call0(Closure* cb) { cb->Run(); }
//   float Call1(ResultCallback2<float, int, float>* cb, int a, float f) {
//     return cb->Run(a, f);
//   }
//
//   struct Foo {
//     float A(const char* label, int a, float f);
//   };
//   float F(const char *label, int a, float f);
//
// Pre-bound arguments work like this. Callback objects store copies of them.
// For by-reference arguments, a copy of the object/primitive that the reference
// refers to is stored inside the callback. When the callback is run,
// the callback's copy is passed by reference to the function.
//
//      Foo* foo = new Foo;
//      NewCallback(foo, &Foo::A)                 ->Run("Y", 10, 3.0f); // 0 + 3
//   == NewCallback(foo, &Foo::A, "Y")            ->Run(10, 3.0f);      // 1 + 2
//   == NewCallback(foo, &Foo::A, "Y", 10)        ->Run(3.0f);          // 2 + 1
//   == NewCallback(foo, &Foo::A, "Y", 10, 3.0f)  ->Run();              // 3 + 0
//   == foo->A("Y", 10, 3.0f);
//
// Calling a function. Were NewPermanentCallback used, memory leak would ensue.
//   NewCallback(&F, "Hello")  ->Run(5, 3.0f);          // == F(10)  // 1 + 2
//
// DO NOT EXPLICITLY WRITE THE TEMPLATE ARGUMENTS WHEN USING
// NewCallback OR NewPermanentCallback(). For example:
//   // DON'T DO THIS.
//   Callback2<int, float>* cb = NewCallback<int, float>(&F, "Hello");
//   // Instead, write:
//   Callback2<int, float>* cb = NewCallback(&F, "Hello")
// If the compiler generates an error due to an overloaded F, add a
// wrapper function in your code that calls the desired overload.

#ifndef GOOGLEAPIS_BASE_CALLBACK_H_
#define GOOGLEAPIS_BASE_CALLBACK_H_

// The actual callback classes and various NewCallback() implementations
// are automatically generated by base/generate-callback-specializations.py.
// We include that output here.
#include "googleapis/base/callback-types.h"  // IWYU pragma: export
#include "googleapis/base/callback-specializations.h"
#include "googleapis/base/macros.h"
namespace googleapis {


// A new barrier closure executes another closure after it has been
// invoked N times, and then deletes itself.
//
// If "N" is zero, the supplied closure is executed immediately.
// Barrier closures are thread-safe.  They use an atomic operation to
// guarantee a correct count.
//
// If you do not know the value of N when constructing the barrier, you may want
// to use //util/callback's IncrementalBarrier.
//
// REQUIRES N >= 0.
extern Closure* NewBarrierClosure(int N, Closure* done_closure);

// Function that does nothing; can be used to make new no-op closures:
//   NewCallback(&DoNothing)
//   NewPermanentCallback(&DoNothing)
// This is a replacement for the formerly available TheNoopClosure() primitive.
extern void DoNothing();

// AutoClosureRunner executes a closure upon deletion.  This class
// is similar to unique_ptr: it is typically stack-allocated and can be
// used to perform some type of cleanup upon exiting a block.
//
// Note: use of AutoClosureRunner with Closures that must be executed at
// specific points is discouraged, since the point at which the Closure
// executes is not explicitly marked.  For example, consider a Closure
// that should execute after a mutex has been released.  The following
// code looks correct, but executes the Closure too early (before release):
// {
//   MutexLock l(...);
//   AutoClosureRunner r(run_after_unlock);
//   ...
// }
// AutoClosureRunner is primarily intended for cleanup operations that
// are relatively independent from other code.
//
// The Reset() method replaces the callback with a new callback. The new
// callback can be supplied as NULL to disable the AutoClosureRunner. This is
// intended as part of a strategy to execute a callback at all exit points of a
// method except where Reset() was called. This method must be used only with
// non-permanent callbacks. The Release() method disables and returns the
// callback, instead of deleting it.
class AutoClosureRunner {
 private:
  Closure* closure_;
 public:
  explicit AutoClosureRunner(Closure* c) : closure_(c) {}
  ~AutoClosureRunner() { if (closure_) closure_->Run(); }
  void Reset(Closure *c) { delete closure_; closure_ = c; }
  Closure* Release() { Closure* c = closure_; closure_ = NULL; return c; }
  bool empty() const { return closure_ == NULL; }
 private:
  DISALLOW_COPY_AND_ASSIGN(AutoClosureRunner);
};
// Catch bug where variable name is omitted, e.g. AutoClosureRunner(c);
#define AutoClosureRunner(x) \
  COMPILE_ASSERT(0, auto_closure_runner_decl_missing_var_name)

// DeletePointerClosure can be used to create a closure that calls delete
// on a pointer.  Here is an example:
//
//  thread->Add(DeletePointerClosure(expensive_to_delete));
//
template<typename T>
void DeletePointer(T* p) {
  delete p;
}

template<typename T>
Closure* DeletePointerClosure(T* p) {
  return NewCallback(&DeletePointer<T>, p);
}

}  // namespace googleapis
#endif  // GOOGLEAPIS_BASE_CALLBACK_H_
